package org.jeecg.modules.basic.warehouse.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.apache.commons.lang.StringUtils;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.common.system.vo.DictModel;
import org.jeecg.modules.basic.warehouse.entity.WmsBasicWarehouseAreaLocation;
import org.jeecg.modules.basic.warehouse.mapper.WmsBasicWarehouseMapper;
import org.jeecg.modules.basic.warehouse.service.IWmsBasicWarehouseAreaLocationService;
import org.jeecg.modules.business.repertory.entity.WmsRepertory;
import org.jeecg.modules.business.repertory.mapper.WmsRepertoryMapper;
import org.jeecg.modules.basic.warehouse.entity.WmsBasicWarehouse;
import org.jeecg.modules.basic.warehouse.entity.WmsBasicWarehouseArea;
import org.jeecg.modules.basic.warehouse.mapper.WmsBasicWarehouseAreaMapper;
import org.jeecg.modules.basic.warehouse.service.IWmsBasicWarehouseAreaService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description: 仓库-库区
 * @Author: jeecg-boot
 * @Date: 2023-08-09
 * @Version: V1.0
 */
@Service
public class WmsBasicWarehouseAreaServiceImpl extends ServiceImpl<WmsBasicWarehouseAreaMapper, WmsBasicWarehouseArea> implements IWmsBasicWarehouseAreaService {

    @Resource
    private WmsRepertoryMapper wmsRepertoryMapper;
    @Resource
    private WmsBasicWarehouseMapper wmsBasicWarehouseMapper;
    @Resource
    private ISysBaseAPI iSysBaseAPI;
    @Autowired
    @Lazy
    private IWmsBasicWarehouseAreaLocationService warehouseAreaLocationService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveByCheck(WmsBasicWarehouseArea wmsBasicWarehouseArea) {
        // 生产站点校验重复
        this.checkProductSite(wmsBasicWarehouseArea);
        if (ObjectUtil.isEmpty(wmsBasicWarehouseArea.getWmsBasicWarehouseId())) {
            throw new JeecgBootException("所选库区没有绑定仓库id！");
        }
        List<WmsBasicWarehouseArea> nameList = this.list(new LambdaQueryWrapper<WmsBasicWarehouseArea>()
                .eq(WmsBasicWarehouseArea::getWmsBasicWarehouseId, wmsBasicWarehouseArea.getWmsBasicWarehouseId())
                .eq(WmsBasicWarehouseArea::getName, wmsBasicWarehouseArea.getName()));
        if (ObjectUtil.isNotEmpty(nameList)) {
            throw new JeecgBootException("库区名称重复！");
        }
        List<WmsBasicWarehouseArea> codeList = this.list(new LambdaQueryWrapper<WmsBasicWarehouseArea>()
                .eq(WmsBasicWarehouseArea::getWmsBasicWarehouseId, wmsBasicWarehouseArea.getWmsBasicWarehouseId())
                .eq(WmsBasicWarehouseArea::getCode, wmsBasicWarehouseArea.getCode()));
        if (ObjectUtil.isNotEmpty(codeList)) {
            throw new JeecgBootException("库区编码重复！");
        }
        this.save(wmsBasicWarehouseArea);
        // 更新上级仓库容量
        this.updateWarehouseCapacity(wmsBasicWarehouseArea.getWmsBasicWarehouseId());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateByCheck(WmsBasicWarehouseArea wmsBasicWarehouseArea) {
        List<WmsBasicWarehouseArea> warehouseAreas = this.list(new LambdaQueryWrapper<WmsBasicWarehouseArea>()
                .eq(WmsBasicWarehouseArea::getWmsBasicWarehouseId, wmsBasicWarehouseArea.getWmsBasicWarehouseId()));
        for (WmsBasicWarehouseArea warehouseArea : warehouseAreas) {
            warehouseArea.setByDefault("0");
        }
        // 批量重置默认库区
        this.updateBatchById(warehouseAreas);
        WmsBasicWarehouseArea originArea = this.getById(wmsBasicWarehouseArea.getId());
        // 生产站点校验重复
        this.checkProductSite(wmsBasicWarehouseArea);
        if (ObjectUtil.isEmpty(wmsBasicWarehouseArea.getWmsBasicWarehouseId())) {
            throw new JeecgBootException("所选库区没有绑定仓库id！");
        }
        List<WmsBasicWarehouseArea> nameList = this.list(new LambdaQueryWrapper<WmsBasicWarehouseArea>()
                .eq(WmsBasicWarehouseArea::getWmsBasicWarehouseId, wmsBasicWarehouseArea.getWmsBasicWarehouseId())
                .eq(WmsBasicWarehouseArea::getName, wmsBasicWarehouseArea.getName())
                .ne(WmsBasicWarehouseArea::getId, wmsBasicWarehouseArea.getId()));
        if (ObjectUtil.isNotEmpty(nameList)) {
            throw new JeecgBootException("库区名称重复！");
        }
        List<WmsBasicWarehouseArea> codeList = this.list(new LambdaQueryWrapper<WmsBasicWarehouseArea>()
                .eq(WmsBasicWarehouseArea::getWmsBasicWarehouseId, wmsBasicWarehouseArea.getWmsBasicWarehouseId())
                .eq(WmsBasicWarehouseArea::getCode, wmsBasicWarehouseArea.getCode())
                .ne(WmsBasicWarehouseArea::getId, wmsBasicWarehouseArea.getId()));
        if (ObjectUtil.isNotEmpty(codeList)) {
            throw new JeecgBootException("库区编码重复！");
        }
        if ("0".equals(wmsBasicWarehouseArea.getStatus())) {
            List<WmsRepertory> list = wmsRepertoryMapper.selectList(new LambdaQueryWrapper<WmsRepertory>().eq(WmsRepertory::getWmsBasicWarehouseAreaId, wmsBasicWarehouseArea.getId()));
            if (ObjectUtil.isNotEmpty(list)) {
                throw new JeecgBootException("该库区有库存物料，不可禁用！");
            }
        }
        this.updateById(wmsBasicWarehouseArea);
        this.update(new LambdaUpdateWrapper<WmsBasicWarehouseArea>()
                .eq(WmsBasicWarehouseArea::getId, wmsBasicWarehouseArea.getId())
                .set(WmsBasicWarehouseArea::getMaxCapacity, wmsBasicWarehouseArea.getMaxCapacity())
                .set(WmsBasicWarehouseArea::getMaxCapacityAssist, wmsBasicWarehouseArea.getMaxCapacityAssist())
                .set(WmsBasicWarehouseArea::getMinCapacity, wmsBasicWarehouseArea.getMinCapacity())
                .set(WmsBasicWarehouseArea::getMinCapacityAssist, wmsBasicWarehouseArea.getMinCapacityAssist())
                .set(WmsBasicWarehouseArea::getWarningCapacity, wmsBasicWarehouseArea.getWarningCapacity())
                .set(WmsBasicWarehouseArea::getWarningCapacityAssist, wmsBasicWarehouseArea.getWarningCapacityAssist()));
        //更新对应仓库的值
        this.updateWarehouseCapacity(wmsBasicWarehouseArea.getWmsBasicWarehouseId());
        // 若库区禁用则将下面的库位都禁用
        if ("0".equals(wmsBasicWarehouseArea.getStatus())) {
            warehouseAreaLocationService.update(new LambdaUpdateWrapper<WmsBasicWarehouseAreaLocation>()
                    .eq(WmsBasicWarehouseAreaLocation::getWmsBasicWarehouseAreaId, wmsBasicWarehouseArea.getId())
                    .set(WmsBasicWarehouseAreaLocation::getStatus, "0"));
        }
    }

    /**
     * 更新对应仓库的容量值
     * @param warehouseId
     */
    private void updateWarehouseCapacity(String warehouseId) {
        List<WmsBasicWarehouseArea> areaList = this.list(new LambdaQueryWrapper<WmsBasicWarehouseArea>()
                .eq(WmsBasicWarehouseArea::getWmsBasicWarehouseId, warehouseId)
        );
        WmsBasicWarehouse warehouse = wmsBasicWarehouseMapper.selectById(warehouseId);
        warehouse.setMaxCapacity(areaList.stream().filter(s->ObjectUtil.isNotNull(s.getMaxCapacity())).map(WmsBasicWarehouseArea::getMaxCapacity).reduce(BigDecimal.ZERO, BigDecimal::add));
        warehouse.setMaxCapacityAssist(areaList.stream().filter(s->ObjectUtil.isNotNull(s.getMaxCapacityAssist())).map(WmsBasicWarehouseArea::getMaxCapacityAssist).reduce(BigDecimal.ZERO, BigDecimal::add));
        warehouse.setWarningCapacity(areaList.stream().filter(s->ObjectUtil.isNotNull(s.getWarningCapacity())).map(WmsBasicWarehouseArea::getWarningCapacity).reduce(BigDecimal.ZERO, BigDecimal::add));
        warehouse.setWarningCapacityAssist(areaList.stream().filter(s->ObjectUtil.isNotNull(s.getWarningCapacityAssist())).map(WmsBasicWarehouseArea::getWarningCapacityAssist).reduce(BigDecimal.ZERO, BigDecimal::add));
        warehouse.setMinCapacity(areaList.stream().filter(s->ObjectUtil.isNotNull(s.getMinCapacity())).map(WmsBasicWarehouseArea::getMinCapacity).reduce(BigDecimal.ZERO, BigDecimal::add));
        warehouse.setMinCapacityAssist(areaList.stream().filter(s->ObjectUtil.isNotNull(s.getMinCapacityAssist())).map(WmsBasicWarehouseArea::getMinCapacityAssist).reduce(BigDecimal.ZERO, BigDecimal::add));
        if ("Y".equals(warehouse.getIsUseArea())){
            wmsBasicWarehouseMapper.updateById(warehouse);
        }
    }

    /**
     * 校验生产站点是否重复
     */
    private void checkProductSite(WmsBasicWarehouseArea wmsBasicWarehouseArea) {
        if (StringUtils.isBlank(wmsBasicWarehouseArea.getProductSite())) {
            return;
        }
        List<DictModel> dicts = iSysBaseAPI.getDictItems("cross_cut_material_site");
        Map<String, String> siteMap = dicts.stream().collect(Collectors.toMap(DictModel::getValue, DictModel::getText, (key1, key2) -> key2));
        List<String> strings = new ArrayList<>();
        String[] sites = wmsBasicWarehouseArea.getProductSite().split(",");
        List<WmsBasicWarehouseArea> list = this.list(new LambdaQueryWrapper<WmsBasicWarehouseArea>()
                .eq(WmsBasicWarehouseArea::getWmsBasicWarehouseId, wmsBasicWarehouseArea.getWmsBasicWarehouseId()));
        for (int i = 0; i < sites.length; i++) {
            for (WmsBasicWarehouseArea area : list) {
                if (!ObjectUtil.equal(wmsBasicWarehouseArea.getId(), area.getId()) && StringUtils.isNotBlank(area.getProductSite())) {
                    String[] split = area.getProductSite().split(",");
                    if (Arrays.asList(split).contains(sites[i])) {
                        strings.add(siteMap.get(sites[i]));
                        break;
                    }
                }
            }
        }
        if (strings.size() > 0) {
            throw new JeecgBootException("生产站点 " + StringUtils.join(strings, ",") + " 已被使用");
        }
    }
}
